package com.zc.auth.security.core.configuration.adapter;

import com.zc.auth.security.core.authentication.AuthenticationTokenService;
import com.zc.auth.security.core.filter.WebFluxAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authorization.AuthorizationWebFilter;
import org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter;
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;

/**
 * webflux支持的自动配置
 *
 * @author zcj
 * @version 1.0.0
 * @date 2022/1/13 10:09
 */
@Configuration(proxyBeanMethods = false)
public class WebFluxSecurityConfigureAdapter {

    @Autowired
    private ServerAccessDeniedHandler monoRoleAccessDeniedHandler;
    @Autowired
    private AuthenticationTokenService authenticationTokenService;
    @Autowired
    private ReactiveAuthorizationManager reactiveAuthorizationManager;

    final public SecurityWebFilterChain webfluxWebFilterChain(ServerHttpSecurity http) {
        http = customerConfigure(http);
        ServerHttpSecurity.FormLoginSpec loginSpec = http.formLogin();
        return loginSpec
                .and()
                .formLogin().disable()
                .cors()
                .and()
                .csrf().disable()
                .exceptionHandling().accessDeniedHandler(monoRoleAccessDeniedHandler)
                .and()
                .addFilterAt(new WebFluxAuthenticationFilter(authenticationTokenService), SecurityWebFiltersOrder.AUTHENTICATION)
                .addFilterAt(new AuthorizationWebFilter(reactiveAuthorizationManager), SecurityWebFiltersOrder.AUTHORIZATION)
                .addFilterAt(exceptionTranslationWebFilter(), SecurityWebFiltersOrder.EXCEPTION_TRANSLATION)
                .build();
    }


    /**
     * 异常处理过滤器
     *
     * @return
     */
    private ExceptionTranslationWebFilter exceptionTranslationWebFilter() {
        ExceptionTranslationWebFilter translationWebFilter = new ExceptionTranslationWebFilter();
        translationWebFilter.setAccessDeniedHandler(monoRoleAccessDeniedHandler);
        return translationWebFilter;
    }


    /**
     * 子类拓展
     *
     * @param http
     * @return
     */
    protected ServerHttpSecurity customerConfigure(ServerHttpSecurity http) {
        return http;
    }


}
